package study.top.mydb;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import study.top.common.DBHandler;
import study.top.common.DateTime;
import study.top.common.TopCommon;
import study.top.mydb.items.PaymentInfoItem;

/**
 * 결제-회원 테이블
 * 
 * 결제정보추가(add), 결제정보수정(edit), 결제정보삭제(delete), 
 * 결제정보보기(show), 회원별 결제내역보기(showListMember), 
 * 모든회원 결제내역보기(showListAll), 총적립금보기(allPoint)
 * 모든회원 결제내역에 페이지 적용(pagingShowListAll)
 * 
 * @author 김미홍
 */
public class PaymentInfo {
	static Logger logger = Logger.getLogger(PaymentInfo.class);	
	
	DBHandler db = null;
			
	public PaymentInfo() {		
		db = DBHandler.getInstance();
	}
		
	private static final String TABLE = "payment_info";
	private static final double Point = 0.005;
	
	/**
	 * 회원이 결제한 총금액및 포인트, 배송지 정보를 등록한다.
	 * 
	 * @param member_seq		결제한 회원
	 * @param total				결제금액
	 * @param zipcode			배송지 우편번호
	 * @param add1				배송지 주소1
	 * @param add2				배송지 주소2
	 * @return int seq			결제 일련번호
	 */
	public int add(int member_seq, int total, int point,
			String zipcode, String add1, String add2) {
		logger.debug("==========method start >> add");
		
		logger.debug("[PARAMS] member_seq=" + member_seq);
		logger.debug("[PARAMS] total=" + total);
		logger.debug("[PARAMS] point=" + point);
		logger.debug("[PARAMS] zipcode=" + zipcode);
		logger.debug("[PARAMS] address1=" + add1);
		logger.debug("[PARAMS] address2=" + add2);

		int seq = -1;

		// SQL 인젝션 방어
		zipcode = zipcode.replace("'", "\'");
		add1 = add1.replace("'", "\'");
		add2 = add2.replace("'", "\'");
				
		// 트랜젝션
		db.beginTrans();
				
		// sql
		String sql = "INSERT INTO payment_info"
				+ "(member_seq, total, point, zipcode, add1, add2, reg_date, edit_date) "
				+ "VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', '%s');";
		
		String date = DateTime.getInstance().getNowDateTimeString();
				
		boolean result = db.execSql(sql, member_seq, total, point, 
				zipcode, add1, add2, date, date);
				
		if(result) {
			db.commit();
			seq = db.getMax(TABLE, "seq", null);
			logger.debug("처리결과 >> " + seq + "결제가 완료되었습니다.");
		} else {
			db.rollback();
			logger.error("처리결과 >> 결제 실패");
		}
			
		logger.debug("==========method end >> add");
		return seq;
	}
	
	/**
	 * 결제 내역을 수정한다.
	 * 
	 * @param seq				결제 일련번호
	 * @param member_seq		결제한 회원
	 * @param total				결제금액
	 * @param zipcode			배송지 우편번호
	 * @param add1				배송지 주소1
	 * @param add2				배송지 주소2
	 * @param reg_date			DB 등록일
	 * @param edit_date			DB 수정일
	 * @return boolean result	수정 여부
	 */
	public boolean edit(int seq, int member_seq, int total,
			String zipcode, String add1, String add2) {
		logger.debug("==========method start >> edit");
		
		logger.debug("[PARAMS] member_seq=" + member_seq);
		logger.debug("[PARAMS] total=" + total);
		logger.debug("[PARAMS] zipcode=" + zipcode);
		logger.debug("[PARAMS] address1=" + add1);
		logger.debug("[PARAMS] address2=" + add2);

		boolean result = false;

		// SQL 인젝션 방어
		zipcode = zipcode.replace("'", "\'");
		add1 = add1.replace("'", "\'");
		add2 = add2.replace("'", "\'");
						
		// 트랜젝션
		db.beginTrans();
			
		String date = DateTime.getInstance().getNowDateTimeString();
		
		// sql 
		String sql = "UPDATE payment_info SET "
				+ "total=%d, point=%d, zipcode='%s', add1='%s', add2='%s', edit_date='%s')";
							
		result = db.execSql(sql, total, total*Point, zipcode, add1, add2, date);
				
		if(result) {
			db.commit();
			logger.debug("처리결과 >> " + seq + "번 주문정보 수정 성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 결제정보 수정 실패");
		}
				
		logger.debug("==========method end >> edit");		
		return result;
	}
	
	/**
	 * 회원이 취소한 결제정보를 삭제한다.
	 * 
	 * @param seq				회원 일련번호
	 * @return boolean result	삭제 여부
	 */
	public boolean delete(int mem_seq) {
		logger.debug("==========method start >> delete");
		
		logger.debug("[PARAMS] mem_seq=" + mem_seq);

		boolean result1 = false, result2 = false;

		db.beginTrans();
		
		// sql - payment_p의 등록된 상품들을 검색해서 삭제후 payment_info 테이블을 삭제한다.
		String sql1 = "DELETE FROM payment_p WHERE payment_info_seq IN (SELECT seq FROM payment_info WHERE member_seq=%d)";
		
		result1 = db.execSql(sql1, mem_seq);
		
		String sql2 = "DELETE FROM payment_info WHERE member_seq=%d";
				
		result2 = db.execSql(sql2, mem_seq);
		
		if(result1 && result2) {
			db.commit();
			logger.debug("처리결과 >> " + mem_seq + "번 회원의 결제정보 삭제 성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 결제정보 삭제 실패 ");
		}
		
		logger.debug("==========method end >> delete");		
		return result1 && result2;
	}
	
	/**
	 * 결제정보 1건을 보여준다.
	 * 
	 * @param seq				결제 일련번호
	 * @return PaymentInfoItem	결제정보 	
	 */
	public PaymentInfoItem show(int seq) {
		logger.debug("==========method start >> show");
		
		logger.debug("[PARAMS] seq=" + seq);		

		PaymentInfoItem item = null;
		
		// sql 
		String sql = "SELECT seq, member_seq, total, point, zipcode, add1, add2, reg_date, edit_date "
				+ "FROM payment_info WHERE seq=%d";
		
		ResultSet rs = db.getResult(sql, seq);
			
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				rs.next();
					
				// 1) ResultSet의 모든 데이터를 변수로 추출
				int no = rs.getInt(1);
				int member_seq = rs.getInt(2);
				int total = rs.getInt(3);
				int point = rs.getInt(4);
				String zipcode = rs.getString(5);
				String add1 = rs.getString(6);
				String add2 = rs.getString(7);
				String reg_date = rs.getString(8);
				String edit_date = rs.getString(9);
								
				// 2) 추출된 값을 객체로 구성
				item = new PaymentInfoItem(no, member_seq, total, point, zipcode, add1, add2, reg_date, edit_date);
			
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 3) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
					
		if(item == null) {
			logger.error("결제정보 1건 조회 실패");
		} else {
			logger.debug("결제정보 1건 조회 성공");
			logger.debug(item.toString());
		}
				
		logger.debug("==========method end >> show");		
		return item;
	}
	
	/**
	 * 회원별 결제정보를 보여준다.
	 * 
	 * @param member_seq					결제한 회원
	 * @return ArrayList<PaymentInfoItem>	결제정보
	 */
	public ArrayList<PaymentInfoItem> showListMember(int member_seq) {
		logger.debug("==========method start >> showListMember");
		
		logger.debug("[PARAMS] member_seq=" + member_seq);
		
		ArrayList<PaymentInfoItem> list = null;
		
		// sql - 수정
		String sql = "SELECT seq, member_seq, total, point, zipcode, add1, add2, reg_date, edit_date "
				+ "FROM payment_info WHERE member_seq=%d ORDER BY seq desc";
				
		ResultSet rs = db.getResult(sql, member_seq);
								
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<PaymentInfoItem>();
								
				while(rs.next()) {
										
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int no = rs.getInt(1);
					int m_seq = rs.getInt(2);
					int total = rs.getInt(3);
					int point = rs.getInt(4);
					String zipcode = rs.getString(5);
					String add1 = rs.getString(6);
					String add2 = rs.getString(7);
					String reg_date = rs.getString(8);
					String edit_date = rs.getString(9);					
					
					// 2) 추출된 값을 객체로 구성
					PaymentInfoItem item = new PaymentInfoItem(no, m_seq, total, point, zipcode, add1, add2, reg_date, edit_date);
						
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
						
		if(list == null) {
			logger.error("회원의 모든 결제정보 조회 실패");
		} else {
			logger.debug("회원의 모든 결제정보 조회 성공 >> " + list.size() + "건 조회됨");
		}
				
		logger.debug("==========method end >> showListMember");
		return list;
	}
	
	/**
	 * TOP에서 주문된 모든 결제내역을 보여준다.
	 * 
	 * @return ArrayList<PaymentInfoItem>	결제정보
	 */
	public ArrayList<PaymentInfoItem> showListAll() {
		logger.debug("==========method start >> showListAll");
		
		ArrayList<PaymentInfoItem> list = null;
		
		// sql - 수정
		String sql = "SELECT seq, member_seq, total, point, zipcode, add1, add2, reg_date, edit_date "
				+ "FROM payment_info ORDER BY seq desc";
						
		ResultSet rs = db.getResult(sql);
								
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<PaymentInfoItem>();
								
				while(rs.next()) {
												
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int no = rs.getInt(1);
					int m_seq = rs.getInt(2);
					int total = rs.getInt(3);
					int point = rs.getInt(4);
					String zipcode = rs.getString(5);
					String add1 = rs.getString(6);
					String add2 = rs.getString(7);
					String reg_date = rs.getString(8);
					String edit_date = rs.getString(9);
							
					// 2) 추출된 값을 객체로 구성
					PaymentInfoItem item = new PaymentInfoItem(no, m_seq, total, point, zipcode, add1, add2, reg_date, edit_date);
								
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
								
		if(list == null) {
			logger.error("결제정보 전체 조회 실패");
		} else {
			logger.debug("결제정보 전체 조회 성공 >> " + list.size() + "건 조회됨");
		}
				
		logger.debug("==========method end >> showListAll");
		return list;
	}
	
	/**
	 * 회원별 적립된 포인트 총액을 보여준다. 
	 * 
	 * total 금액과 대비하여 적립률이 낮거나 -값인 경우
	 * 적립금을 사용한 것으로 생각한다.
	 * 
	 * @param member_seq	결제한 회원
	 * @return int allPoint	사용 가능한 포인트 적립 총액
	 */
	public int allPoint(int member_seq) {
		logger.debug("==========method start >> allPoint");
		
		logger.debug("[PARAMS] member_seq=" + member_seq);

		int allPoint = 0;
		
		ArrayList<PaymentInfoItem> list = null;
		
		list = showListMember(member_seq);
	
		if (list != null) {				
			for(int i = 0; i < list.size(); i++) {
				allPoint += list.get(i).getPoint();
			}
		} else {
			logger.error("리스트 가져오기 실패");
		}
		
		logger.debug("==========method end >> allPoint");
		return allPoint;
	}	
	
	/**
	 * TOP에서 주문된 결제내역에 페이지 추가
	 * 
	 * @param start		회원 일련번호
	 * @param start		페이지의 시작 목록번호
	 * @param end		페이지의 끝 목록번호 
	 * @return ArrayList<PaymentInfoItem>	결제정보
	 */
	public ArrayList<PaymentInfoItem> pagingShowListMember(int member_seq, int start, int end) {
		logger.debug("==========method start >> pagingShowListAll");
		
		logger.debug("[PARAMS] start=" + start);
		logger.debug("[PARAMS] end=" + end);
		
		ArrayList<PaymentInfoItem> list = null;
		
		// sql - 수정
		String sql = "SELECT seq, member_seq, total, point, zipcode, add1, add2, reg_date, edit_date "
				+ "FROM payment_info WHERE member_seq=%d ORDER BY seq desc LIMIT %d, %d";
						
		ResultSet rs = db.getResult(sql, member_seq, start, end);
								
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<PaymentInfoItem>();
								
				while(rs.next()) {
												
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int no = rs.getInt(1);
					int m_seq = rs.getInt(2);
					int total = rs.getInt(3);
					int point = rs.getInt(4);
					String zipcode = rs.getString(5);
					String add1 = rs.getString(6);
					String add2 = rs.getString(7);
					String reg_date = rs.getString(8);
					String edit_date = rs.getString(9);
							
					// 2) 추출된 값을 객체로 구성
					PaymentInfoItem item = new PaymentInfoItem(no, m_seq, total, point, zipcode, add1, add2, reg_date, edit_date);
								
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
								
		if(list == null) {
			logger.error("결제정보 전체 조회 실패");
		} else {
			logger.debug("결제정보 전체 조회 성공 >> " + list.size() + "건 조회됨");
		}
				
		logger.debug("==========method end >> pagingShowListAll");
		return list;
	}
	
	/**
	 * TOP에서 주문된 모든 결제내역에 페이지 추가
	 * 
	 * @param start		페이지의 시작 목록번호
	 * @param end		페이지의 끝 목록번호 
	 * @return ArrayList<PaymentInfoItem>	결제정보
	 */
	public ArrayList<PaymentInfoItem> pagingShowListAll(int start, int end) {
		logger.debug("==========method start >> pagingShowListAll");
		
		logger.debug("[PARAMS] start=" + start);
		logger.debug("[PARAMS] end=" + end);
		
		ArrayList<PaymentInfoItem> list = null;
		
		// sql - 수정
		String sql = "SELECT seq, member_seq, total, point, zipcode, add1, add2, reg_date, edit_date "
				+ "FROM payment_info ORDER BY seq desc LIMIT %d, %d";
						
		ResultSet rs = db.getResult(sql, start, end);
								
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<PaymentInfoItem>();
								
				while(rs.next()) {
												
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int no = rs.getInt(1);
					int m_seq = rs.getInt(2);
					int total = rs.getInt(3);
					int point = rs.getInt(4);
					String zipcode = rs.getString(5);
					String add1 = rs.getString(6);
					String add2 = rs.getString(7);
					String reg_date = rs.getString(8);
					String edit_date = rs.getString(9);
							
					// 2) 추출된 값을 객체로 구성
					PaymentInfoItem item = new PaymentInfoItem(no, m_seq, total, point, zipcode, add1, add2, reg_date, edit_date);
								
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
								
		if(list == null) {
			logger.error("결제정보 전체 조회 실패");
		} else {
			logger.debug("결제정보 전체 조회 성공 >> " + list.size() + "건 조회됨");
		}
				
		logger.debug("==========method end >> pagingShowListAll");
		return list;
	}
}